package com.example.service.impl;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.common.BusinessExceptionUtils;
import com.example.dto.CashOutMsg;
import com.example.mapper.CashOutMapper;
import com.example.mq.sender.IMsgSender;
import com.example.po.CashOutPO;
import com.example.service.AccountService;
import com.example.service.CashOutService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/*
@description:
@ClassName CashOutServiceImpl
@author chen
@create 2025-08-29 17:06
@Version 1.0
*/
@Slf4j
@Service
public class CashOutServiceImpl extends ServiceImpl<CashOutMapper, CashOutPO> implements CashOutService
{
    @Autowired
    private AccountService accountService;
    @Autowired
    private IMsgSender msgSender;
    @Autowired
    private TransactionTemplate transactionTemplate;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String cashOut(String accountId, BigDecimal price)
    {
        //1、扣减账户余额
        this.accountService.balanceSubtract(accountId, price);

        //2、创建提现记录
        CashOutPO cashOutPO = this.createCashOutPO(accountId, price);

        //3、发送提现消息（必须是事务消息）
        this.sendCashOutMsg(cashOutPO);
        return cashOutPO.getId();
    }

    @Override
    public void disposeCashOutMsg(CashOutMsg cashOutMsg)
    {
        String cashOutId = cashOutMsg.getCashOutId();
        CashOutPO cashOutPO = this.getById(cashOutId);
        if (cashOutPO == null)
            throw BusinessExceptionUtils.businessException("提现记录不存在");
        //若处理成功了，直接返回
        if (cashOutPO.getStatus() == 100)
            return;
        this.wechatTransfer(cashOutPO);
        /**
         * 2、将提现记录状态置为成功
         */
        this.cashOutSuccess(cashOutId);
    }

    private void cashOutSuccess(String cashOutId)
    {
        this.transactionTemplate.executeWithoutResult(action ->
        {
            // update t_cash_out set status = 100, update_time = #{当前时间} where id = #{cashOutId} and status = 0
            LambdaUpdateWrapper<CashOutPO> updateWrapper = Wrappers.lambdaUpdate(CashOutPO.class)
                    .eq(CashOutPO::getId, cashOutId)
                    .eq(CashOutPO::getStatus, 0)
                    .set(CashOutPO::getStatus, 100)
                    .set(CashOutPO::getUpdateTime, LocalDateTime.now());
            if (!this.update(updateWrapper))
            {
                String jsonStr = JSONUtil.toJsonStr(this.getById(cashOutId));
                log.error("更新转账记录失败:{}", jsonStr);
                throw BusinessExceptionUtils.businessException("更新转账记录失败");
            }
            //若还有其他操作，可以写到这里
        });
    }

    private void wechatTransfer(CashOutPO cashOutPO) {
        // 调用微信体现接口
    }


    private void sendCashOutMsg(CashOutPO cashOutPO) {
        CashOutMsg cashOutMsg = CashOutMsg.builder().cashOutId(cashOutPO.getId()).build();
        this.msgSender.send(cashOutMsg);
    }




    private CashOutPO createCashOutPO(String accountId, BigDecimal price)
    {
        CashOutPO cashOutPO = new CashOutPO();
        cashOutPO.setId(IdUtil.fastSimpleUUID());
        cashOutPO.setAccountId(accountId);
        cashOutPO.setPrice(price);
        cashOutPO.setStatus(0); //待处理
        cashOutPO.setCreateTime(LocalDateTime.now());
        this.save(cashOutPO);
        return cashOutPO;
    }
}
